﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using yule.CodeBuilder.Core.PDM;

namespace yule.CodeBuilder.Core
{
    /// <summary>
    /// 生成类型
    /// </summary>
    public enum BuildType
    {
        /// <summary>
        /// 实体基类
        /// </summary>
        BaseModel,
        /// <summary>
        /// 实体类
        /// </summary>
        Model,
        /// <summary>
        /// 数据库访问基类
        /// </summary>
        BaseDAL,
        /// <summary>
        /// 数据库访问类
        /// </summary>
        DAL,
        /// <summary>
        /// 接口
        /// </summary>
        IDAL
    }

    public class BuilderFactory
    {
        public static IBuilder GetBuilder(TableInfo table, BuildType type)
        {
            IBuilder builder = null;
            switch (type)
            {
                case BuildType.BaseModel:
                    builder = new BaseModelBuilder(table);
                    break;
                case BuildType.Model:
                    builder = new ModelBuilder(table);
                    break;
                case BuildType.BaseDAL:
                    builder = new BaseDALBuilder(table);
                    break;
                case BuildType.DAL:
                    builder = new DALBuilder(table);
                    break;
                case BuildType.IDAL:
                    builder = new IDALBuilder(table);
                    break;
            }
            return builder;
        }
    }

    public interface IBuilder
    {
        /// <summary>
        /// 命名空间
        /// </summary>
        string NameSpace { get; }
        /// <summary>
        /// 类名
        /// </summary>
        string ClassName { get; }
        /// <summary>
        /// 类名
        /// </summary>
        string ClassFullName { get; }
        /// <summary>
        /// 路径
        /// 以/结尾
        /// </summary>
        string Path { get; }
        /// <summary>
        /// 文件名
        /// </summary>
        string FileName { get; }
        /// <summary>
        /// 文件全名
        /// Path+FileName
        /// </summary>
        string FileFullName { get; }
    }

    /// <summary>
    /// 生成基类
    /// </summary>
    public abstract class BaseBuilder : IBuilder
    {
        #region IBuilder 成员

        private string _NameSpace = null;
        /// <summary>
        /// 命名空间
        /// </summary>
        public string NameSpace
        {
            get
            {
                if (this._NameSpace == null)
                {
                    string modeltype = null;

                    for (int i = 0; i < (this.TableSplt.Length - 1); i++)
                    {
                        string splt = this.TableSplt[i];
                        modeltype += modeltype == null ? splt : ("." + splt);
                    }

                    this._NameSpace = string.Format("yule.{0}.{1}", this.BuildTypeName, modeltype);
                }
                return this._NameSpace;
            }
        }

        private string _ClassName = null;
        /// <summary>
        /// 类名
        /// </summary>
        public virtual string ClassName
        {
            get
            {
                if (this._ClassName == null)
                {
                    this._ClassName = this.TableSplt[this.TableSplt.Length - 1];
                }
                return this._ClassName;
            }
        }

        /// <summary>
        /// 类全名
        /// </summary>
        public string ClassFullName
        {
            get
            {
                return this.NameSpace + "." + this.ClassName;
            }
        }

        private string _Path = null;
        /// <summary>
        /// 路径
        /// 以/结尾
        /// </summary>
        public string Path
        {
            get
            {
                if (this._Path == null)
                {
                    string modeltype = null;

                    for (int i = 0; i < (this.TableSplt.Length - 1); i++)
                    {
                        string splt = this.TableSplt[i];
                        modeltype += modeltype == null ? splt : ("/" + splt);
                    }
                    this._Path = string.Format("yule/{0}/{1}/", this.PathTypeName, modeltype);
                }
                return this._Path;
            }
        }

        /// <summary>
        /// 文件名
        /// </summary>
        public string FileName
        {
            get
            {
                return this.ClassName + ".cs";
            }
        }

        /// <summary>
        /// 文件名
        /// </summary>
        public string FileFullName
        {
            get
            {
                return this.Path + this.FileName;
            }
        }

        #endregion

        private string[] _TableSplt = null;
        protected string[] TableSplt
        {
            get
            {
                if (this._TableSplt == null)
                {
                    string[] temps = this.Table.Core.Split('_');
                    this._TableSplt = new string[temps.Length];
                    for (int i = 0; i < temps.Length; i++)
                    {
                        this._TableSplt[i] = temps[i];
                    }
                }
                return this._TableSplt;
            }
        }

        public abstract TableInfo Table { get; }
        /// <summary>
        /// 类型
        /// 不以.结尾  类似Model.Base
        /// </summary>
        public abstract string BuildTypeName { get; }
        /// <summary>
        /// 存放路径
        /// 不以/结尾 类似Model/Base
        /// </summary>
        public abstract string PathTypeName { get; }

    }

    public sealed class BaseModelBuilder : BaseBuilder
    {

        public BaseModelBuilder(TableInfo table)
        {
            this._table = table;
        }
        private TableInfo _table = null;
        public override TableInfo Table
        {
            get { return this._table; }
        }

        public override string BuildTypeName
        {
            get { return "Model.Base"; }
        }

        public override string PathTypeName
        {
            get { return "Model/Base"; }
        }
    }

    public sealed class ModelBuilder : BaseBuilder
    {

        public ModelBuilder(TableInfo table)
        {
            this._table = table;
        }
        private TableInfo _table = null;
        public override TableInfo Table
        {
            get { return this._table; }
        }

        public override string BuildTypeName
        {
            get { return "Model"; }
        }

        public override string PathTypeName
        {
            get { return "Model"; }
        }
    }

    public sealed class BaseDALBuilder : BaseBuilder
    {

        public BaseDALBuilder(TableInfo table)
        {
            this._table = table;
        }
        private TableInfo _table = null;
        public override TableInfo Table
        {
            get { return this._table; }
        }

        public override string BuildTypeName
        {
            get { return "DAL.Base"; }
        }

        public override string PathTypeName
        {
            get { return "DAL/Base"; }
        }
    }

    public sealed class DALBuilder : BaseBuilder
    {

        public DALBuilder(TableInfo table)
        {
            this._table = table;
        }
        private TableInfo _table = null;
        public override TableInfo Table
        {
            get { return this._table; }
        }

        public override string BuildTypeName
        {
            get { return "DAL"; }
        }

        public override string PathTypeName
        {
            get { return "DAL"; }
        }
    }

    public sealed class IDALBuilder : BaseBuilder
    {

        public IDALBuilder(TableInfo table)
        {
            this._table = table;
        }
        private TableInfo _table = null;

        public override TableInfo Table
        {
            get { return this._table; }
        }

        public override string BuildTypeName
        {
            get { return "IDAL"; }
        }

        public override string PathTypeName
        {
            get { return "IDAL"; }
        }


        private string _ClassName = null;
        /// <summary>
        /// 类名
        /// </summary>
        public override string ClassName
        {
            get
            {
                if (this._ClassName == null)
                {
                    this._ClassName = "I" + this.TableSplt[this.TableSplt.Length - 1];
                }
                return this._ClassName;
            }
        }

    }

}

namespace System
{
    public static class StringEx
    {
        public static string FirstUp(this string v)
        {
            if (string.IsNullOrEmpty(v))
            {
                return v;
            }
            else
            {
                v = v.Trim();
                return v.Substring(0, 1).ToUpper() + (v.Length > 1 ? v.Substring(1).ToLower() : "");
            }
        }

    }
}